package jsyf.oa.service.pm;

import com.alibaba.dubbo.common.utils.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import jsyf.com.util.DateUtils;
import jsyf.oa.dao.pm.ProjectDao;
import jsyf.oa.dao.pm.ProjectPlanDao;
import jsyf.oa.dao.pm.ProjectTrackDao;
import jsyf.oa.dao.wechat.service_company.TokenDao;
import jsyf.oa.entity.pm.ProjectEntity;
import jsyf.oa.entity.pm.ProjectTrackEntity;
import jsyf.oa.facade.pm.ProjectTrackFacade;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * Created by wangmin  2018-10-15 10:53:33
 */
@Service
@Transactional(rollbackFor = Exception.class)
@com.alibaba.dubbo.config.annotation.Service(protocol = {"dubbo"})
public class ProjectTrackService implements ProjectTrackFacade {

    @Autowired
    private ProjectDao projectDao;
    @Autowired
    private ProjectPlanDao projectPlanDao;
    @Autowired
    private ProjectTrackDao projectTrackDao;
    @Autowired
    private TokenDao tokenDao;

    @Override
    public List<JSONObject> getProjectList(String jsonData) {
        JSONObject jsonObj = JSON.parseObject(jsonData);
        String level = jsonObj.get("level").toString();
        String projectId = jsonObj.get("projectId").toString();
        String userId = jsonObj.get("userId").toString();

        List<JSONObject> list = projectDao.getProjcetList(level, projectId, userId);

        List<JSONObject> listObj = new ArrayList<>();
        List<String> listId = new ArrayList<>();

        JSONObject jsonObject = new JSONObject();
        for (JSONObject item : list) {
            String id = item.get("ID").toString();
            String parentId = item.get("PARENT_ID").toString();
            String proLevel = item.get("PRO_LEVEL").toString();
            if (proLevel.equals("1") && !jsonObject.containsKey(parentId)) {
                jsonObject.put(id, item);
                listId.add(id);
            } else if (proLevel.equals("2") && jsonObject.containsKey(parentId)) {
                JSONObject level1 = (JSONObject) jsonObject.get(parentId);
                if (level1.containsKey("level2")) {
                    List<JSONObject> jsonObjectList = (List<JSONObject>) level1.get("level2");
                    jsonObjectList.add(item);
                } else {
                    List<JSONObject> jsonObjectList = new ArrayList<>();
                    jsonObjectList.add(item);
                    level1.put("level2", jsonObjectList);
                }
            }
        }

        if (level.equals("3"))
            return list;

        for (String id : listId)
            listObj.add((JSONObject) jsonObject.get(id));

        return listObj;
    }

    private JSONObject getTimeLimit(String jsonData) {
        JSONObject jsonObj = JSON.parseObject(jsonData);
        int positionVal = Integer.parseInt(jsonObj.get("positionVal").toString());
        positionVal = positionVal * 7;

        JSONObject jsonObject = new JSONObject();

        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(calendar.DATE, 0-positionVal);
        jsonObject.put("startDate", DateUtils.parse(calendar.getTime(), "yyyy-MM-dd"));
        calendar.setTime(date);
        calendar.add(calendar.DATE, 60-positionVal);
        jsonObject.put("endDate", DateUtils.parse(calendar.getTime(), "yyyy-MM-dd"));
        return jsonObject;
    }

    @Override
    public JSONObject getMonthList(String jsonData) {
        JSONObject jsonObj = JSON.parseObject(jsonData);
        int positionVal = Integer.parseInt(jsonObj.get("positionVal").toString());
        positionVal = positionVal * 7;
        JSONObject jsonObject = new JSONObject();

        Date date = new Date();
        Calendar calendar = Calendar.getInstance();

        for (int i = 0 - positionVal; i < 60 - positionVal; i++) {
            calendar.setTime(date);
            calendar.add(calendar.DATE, i);
            String strYear = ((Integer) (calendar.get(Calendar.YEAR))).toString();
            String strMonth = ((Integer) (calendar.get(Calendar.MONTH) + 1)).toString();
            String strDay = ((Integer) (calendar.get(Calendar.DATE))).toString();

            String key = strMonth.length() == 1 ? "0" + strMonth : strMonth;

            if (jsonObject.containsKey(key)) {
                List<JSONObject> dateList = ((List<JSONObject>) jsonObject.get(key));
                JSONObject dateObj = new JSONObject();
                dateObj.put("year", strYear);
                dateObj.put("month", strMonth);
                dateObj.put("day", strDay);
                dateObj.put("date", strYear + "-" + strMonth + "-" + strDay);
                dateList.add(dateObj);
            } else {
                List<JSONObject> list = new ArrayList<>();

                JSONObject dateObj = new JSONObject();
                dateObj.put("year", strYear);
                dateObj.put("month", strMonth);
                dateObj.put("day", strDay);
                dateObj.put("date", strYear + "-" + strMonth + "-" + strDay);
                list.add(dateObj);
                jsonObject.put(key, list);
            }
        }
        return jsonObject;
    }

    @Override
    public JSONObject getPlanList(String jsonData) {
        JSONObject jsonObj = JSON.parseObject(jsonData);
        String level = jsonObj.get("level").toString();
        String projectId = jsonObj.get("projectId").toString();
        String startDate = getTimeLimit(jsonData).get("startDate").toString();
        String endDate = getTimeLimit(jsonData).get("endDate").toString();

        List<JSONObject> list = projectDao.getPlanList(startDate, endDate, level, projectId);
        JSONObject jsonObject = new JSONObject();
        for (JSONObject item : list) {
            jsonObject.put(item.get("PROJECT_ID").toString() + item.get("PLAN_DATE").toString(), true);
        }
        return jsonObject;
    }

    @Override
    public JSONObject getTrackList(String jsonData) {
        JSONObject jsonObj = JSON.parseObject(jsonData);
        String level = jsonObj.get("level").toString();
        String projectId = jsonObj.get("projectId").toString();
        String startDate = getTimeLimit(jsonData).get("startDate").toString();
        String endDate = getTimeLimit(jsonData).get("endDate").toString();

        List<JSONObject> list = projectDao.getTrackList(startDate, endDate, level, projectId);
        JSONObject jsonObject = new JSONObject();
        for (JSONObject item : list) {
            jsonObject.put(item.get("PROJECT_ID").toString() + item.get("TRACK_DATE").toString(), item);
        }
        return jsonObject;
    }

    @Override
    public Integer batchAddPlan(String jsonData) {
        JSONObject jsonObject = JSON.parseObject(jsonData);
        String projectId = jsonObject.get("projectId").toString();
        Integer r = projectPlanDao.batchAddPlan((List<JSONObject>) jsonObject.get("planList"));

        noticeTrackPlan(projectId, "", false);
        return r;
    }

    @Override
    public JSONObject getProjectTrackByIdAndTrackDate(String jsonData) {
        JSONObject jsonObject = JSON.parseObject(jsonData);
        String projectId = jsonObject.get("projectId").toString();
        String trackDate = jsonObject.get("trackDate").toString();

        return projectDao.getProjectTrackByIdAndTrackDate(projectId, trackDate);
    }

    @Override
    public Integer saveProjectTrack(String jsonData) {
        JSONObject jsonObject = JSON.parseObject(jsonData);
        String id = jsonObject.get("id").toString();
        ProjectTrackEntity projectTrackEntity = (ProjectTrackEntity) projectTrackDao.convertJson2Entity(jsonObject);
        if (id.isEmpty()) {
            projectTrackDao.add(projectTrackEntity);
            noticeTrackPlan(projectTrackEntity.getProjectId(), projectTrackEntity.getTrackContent(), true);
        } else {
            projectTrackDao.update(projectTrackEntity);
        }
        return 1;
    }

    @Override
    public Integer saveProjectOnwTwoThree(String jsonData) {
        JSONObject jsonObject = JSON.parseObject(jsonData);
        String projectName = jsonObject.get("projectName").toString();
        String principal = jsonObject.get("principal").toString();
        String principalName = jsonObject.get("principalName").toString();
        String userId = jsonObject.get("userId").toString();
        String userName = jsonObject.get("userName").toString();
        String id = jsonObject.get("id").toString();
        String proSn = jsonObject.get("proSn").toString();
        String delIds = jsonObject.get("delIds").toString();
        String changed = jsonObject.get("changed").toString();
        List<JSONObject> jsonObjectList = (List<JSONObject>) jsonObject.get("levelProjectList");
        JSONObject projectObj = new JSONObject();
        projectObj.put("proName", projectName);
        projectObj.put("proPrincipal", principal);
        projectObj.put("createUserId", userId);
        if (StringUtils.isEmpty(id)) {
            id = projectDao.generateKey();
            proSn = projectDao.generateKey();
            projectObj.put("id", id);
            projectObj.put("proSn", proSn);
            ProjectEntity projectEntity = (ProjectEntity) projectDao.convertJson2Entity(projectObj);
            projectDao.addProject(projectEntity);
            noticeCreateProject(userName, projectName, principal, principalName, false, "");
        } else {
            if (changed.equals("true"))
                noticeCreateProject(userName, projectName, principal, principalName, true, id);
            projectObj.put("id", id);
            projectObj.put("proSn", proSn);
            ProjectEntity projectEntity = (ProjectEntity) projectDao.convertJson2Entity(projectObj);
            projectDao.update(projectEntity);
        }

        for (JSONObject jsonObj : jsonObjectList) {
            List<JSONObject> jsonLevel3List = (List<JSONObject>) jsonObj.get("level3List");

            projectName = jsonObj.get("projectName").toString();
            principal = jsonObj.get("principal").toString();
            principalName = jsonObj.get("principalName").toString();
            String level2Id = jsonObj.get("id").toString();
            String sortNo = jsonObj.get("sortNo").toString();
            changed = jsonObj.get("changed").toString();

            projectObj.put("proName", projectName);
            projectObj.put("proPrincipal", principal);
            projectObj.put("proLevel", 2);
            projectObj.put("parentId", id);
            projectObj.put("sortNo", sortNo);
            projectObj.put("id", level2Id);
            ProjectEntity projectEntity = (ProjectEntity) projectDao.convertJson2Entity(projectObj);

            if (StringUtils.isEmpty(level2Id)) {
                projectDao.add(projectEntity);
                noticeCreateProject(userName, projectName, principal, principalName, false, "");
            } else {
                if (changed.equals("true"))
                    noticeCreateProject(userName, projectName, principal, principalName, true, level2Id);
                projectDao.update(projectEntity);
            }

            JSONObject level3Project = new JSONObject();
            for (JSONObject level3Json : jsonLevel3List) {
                projectName = level3Json.get("projectName").toString();
                principal = level3Json.get("principal").toString();
                principalName = level3Json.get("principalName").toString();
                sortNo = level3Json.get("sortNo").toString();
                changed = level3Json.get("changed").toString();
                String level3Id = level3Json.get("id").toString();
                level3Project.put("proName", projectName);
                level3Project.put("proPrincipal", principal);
                level3Project.put("proLevel", 3);
                level3Project.put("parentId", projectEntity.getId());
                level3Project.put("sortNo", sortNo);
                level3Project.put("createUserId", userId);
                level3Project.put("id", level3Id);
                level3Project.put("proSn", proSn);

                ProjectEntity level3Entity = (ProjectEntity) projectDao.convertJson2Entity(level3Project);
                if (StringUtils.isEmpty(level3Id)) {
                    projectDao.add(level3Entity);
                    noticeCreateProject(userName, projectName, principal, principalName, false, "");
                } else {
                    if (changed.equals("true"))
                        noticeCreateProject(userName, projectName, principal, principalName, true, level3Id);

                    projectDao.update(level3Entity);
                }
            }
        }

        if (StringUtils.isNotEmpty(delIds)) {
            StringBuilder sbIds = new StringBuilder();
            for (String proId : delIds.split(",")) {
                sbIds.append("'").append(proId).append("',");
            }
            if (StringUtils.isNotEmpty(sbIds.toString()))
                projectDao.delProjectByIds(sbIds.toString().substring(0, sbIds.length() - 1));
        }
        return 1;
    }

    private void noticeCreateProject(String senderName, String projectName, String toUserId, String toUserName, boolean isModify, String projectId) {
        if (StringUtils.isEmpty(senderName) || StringUtils.isEmpty(toUserName) || StringUtils.isEmpty(projectName))
            return;
        StringBuilder sbMsg = new StringBuilder();
        if (isModify) {
            JSONObject jsonObject = projectDao.getProjectInfoById(projectId);
            String oldPrincipalName = jsonObject.get("thisUserName").toString();
            String oldProjectName = jsonObject.get("projectName").toString();
            sbMsg.append(toUserName + "，你好!\n");
            sbMsg.append(senderName + "修改了项目，\n");
            sbMsg.append("修改前（项目名称：" + oldProjectName + " ，负责人：" + oldPrincipalName + "）；\n");
            sbMsg.append("修改后（项目名称：" + projectName + "，负责人：" + toUserName + "）；");
        } else {
            sbMsg.append(toUserName + "，你好!\n");
            sbMsg.append(senderName + "创建了项目跟踪“");
            sbMsg.append(projectName);
            sbMsg.append("”，需要你添加计划和每日跟踪！");
        }
        //微信通知
        JSONObject msgObject = new JSONObject();
        msgObject.put("userIds", toUserId);
        msgObject.put("content", sbMsg.toString());
        tokenDao.sendTextMsg(JSON.toJSONString(msgObject));
    }

    private void noticeTrackPlan(String projectId, String trackContent, boolean isTrack) {
        JSONObject jsonObject = projectDao.getProjectInfoById(projectId);
        String senderName = jsonObject.get("thisUserName").toString();
        String toUserId = jsonObject.get("upUser").toString();
        String toUserName = jsonObject.get("upUserName").toString();
        String projectName = jsonObject.get("projectName").toString();

        StringBuilder sbMsg = new StringBuilder();
        sbMsg.append(toUserName + "，你好!\n");
        if (isTrack) {
            sbMsg.append(senderName + "跟踪了“");
            sbMsg.append(projectName + "”,跟踪内容：" + trackContent);
        } else {
            sbMsg.append(senderName + "对项目“");
            sbMsg.append(projectName + "”添加了计划");
        }
        sbMsg.append("，请悉知！");
        //微信通知
        JSONObject msgObject = new JSONObject();
        msgObject.put("userIds", toUserId);
        msgObject.put("content", sbMsg.toString());
        tokenDao.sendTextMsg(JSON.toJSONString(msgObject));
    }

    @Override
    public List<JSONObject> getLevel1ProjectList(String jsonData) {
        List<JSONObject> list = projectDao.getLevel1ProjcetList();
        return list;
    }

    @Override
    public JSONObject getLevel1Level2Level3ProjectById(String jsonData) {
        JSONObject jsonObject = JSON.parseObject(jsonData);
        List<JSONObject> list = projectDao.getLevel1Level2Level3ProjectById(jsonObject.get("projectId").toString());
        Map<String, Object> map = new HashedMap();
        JSONObject jsonObj = null;
        JSONObject returnObj = null;
        for (JSONObject jsonO : list) {
            String proLevel = jsonO.get("PRO_LEVEL").toString();
            String id = jsonO.get("id").toString();
            String parentId = jsonO.get("PARENT_ID").toString();
            if (proLevel.equals("1")) {
                map.put(id, jsonO);
                returnObj = jsonO;
            } else if (proLevel.equals("2")) {
                jsonObj = (JSONObject) map.get(parentId);
                List<JSONObject> jsonObjectList = (List<JSONObject>) jsonObj.get("levelProjectList");
                if (jsonObjectList == null) {
                    jsonObjectList = new ArrayList<>();
                    jsonObjectList.add(jsonO);
                    jsonObj.put("levelProjectList", jsonObjectList);
                } else {
                    jsonObjectList.add(jsonO);
                    jsonObj.put("levelProjectList", jsonObjectList);
                }
                map.put(id, jsonO);
            } else if (proLevel.equals("3")) {
                jsonObj = (JSONObject) map.get(parentId);
                List<JSONObject> jsonObjectList = (List<JSONObject>) jsonObj.get("level3List");
                if (jsonObjectList == null) {
                    jsonObjectList = new ArrayList<>();
                    jsonObjectList.add(jsonO);
                    jsonObj.put("level3List", jsonObjectList);
                } else {
                    jsonObjectList.add(jsonO);
                    jsonObj.put("level3List", jsonObjectList);
                }
            }
        }

        return returnObj;
    }

    @Override
    public List<JSONObject> getLevel2ByLevel1Id(String jsonData) {
        JSONObject jsonObject = JSON.parseObject(jsonData);
        List<JSONObject> list = projectDao.getLevel2ByLevel1Id(jsonObject.get("projectId").toString());
        return list;
    }

    @Override
    public Integer saveProjectThree(String jsonData) {
        return projectDao.add(projectDao.convertJson2Entity(JSON.parseObject(jsonData)));
    }

    @Override
    public List<JSONObject> getProjectPrincipalList(String jsonData) {
        JSONObject jsonObject = JSON.parseObject(jsonData);
        String projectId = jsonObject.get("projectId").toString();
        return projectDao.getProjectPrincipalList(projectId);
    }

    @Override
    public List<JSONObject> getTrackListById(String jsonData) {
        JSONObject jsonObject = JSON.parseObject(jsonData);
        String projectId = jsonObject.get("projectId").toString();
        return projectTrackDao.getTrackList(projectId);
    }

    @Override
    public JSONObject getTrackInfoById(String jsonData) {
        JSONObject jsonObject = JSON.parseObject(jsonData);
        String projectId = jsonObject.get("projectId").toString();
        return projectDao.getTrackInfoById(projectId);
    }

    @Override
    public Integer setProjectFinish(String jsonData) {
        JSONObject jsonObject = JSON.parseObject(jsonData);
        String projectSn = jsonObject.get("projectSn").toString();
        return projectDao.setProjectFinish(projectSn);
    }

}
